import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient1 extends JFrame {

    private Socket socket;
    private OutputStream outputStream;
    private InputStream inputStream;
    private final JTextArea chatArea;
    private final JTextField inputField;
    private final JButton sendButton;
    private final JButton offlineButton;
    // 新增：用于控制线程停止的标志位
    private volatile boolean clientThreadControl = true;

    public TCPClient1(String clientName, String serverIp, int serverPort) {
        // 设置窗口标题
        setTitle("聊天室：" + clientName);
        // 设置窗口大小
        setSize(400, 200);
        // 设置窗口关闭操作
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建聊天区域
        chatArea = new JTextArea();
        chatArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(chatArea);

        // 创建输入框
        inputField = new JTextField();
        // 创建发送按钮
        sendButton = new JButton("发送");
        // 创建离线按钮
        offlineButton = new JButton("离线");

        // 设置布局管理器为BorderLayout
        setLayout(new BorderLayout());

        // 先将聊天框所在的滚动面板添加到窗口的中心位置
        add(scrollPane, BorderLayout.CENTER);

        // 创建一个面板用于放置输入框、发送按钮和离线按钮
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

        inputField.setPreferredSize(new Dimension(250, inputField.getPreferredSize().height));

        // 将输入框、发送按钮和离线按钮添加到按钮面板中
        buttonPanel.add(inputField);
        buttonPanel.add(sendButton);
        buttonPanel.add(offlineButton);

        // 将按钮面板添加到窗口的南部（底部）位置
        add(buttonPanel, BorderLayout.SOUTH);
        // 连接到服务器
        try {
            socket = new Socket(serverIp, serverPort);;
            outputStream = socket.getOutputStream();
            inputStream = socket.getInputStream();
            // 获取客户端的IP地址和端口号
            String clientIp = socket.getLocalAddress().getHostAddress();
            int clientPort = socket.getLocalPort();
            setTitle("聊天室：" + clientName + "/" + clientIp + ":" + clientPort);
            // 发送用户名到服务器
            outputStream.write(clientName.getBytes());
            // 启动线程接收服务器消息
            Thread clientThread = new Thread(() -> {
                while (clientThreadControl) {
                    try {
                        byte[] buffer = new byte[1024];
                        int length = inputStream.read(buffer);
                        if(length == -1){
                            continue;
                        }
                        String message = new String(buffer, 0, length);
                        appendMessage(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            clientThread.start();

        } catch (IOException e) {
            clientThreadControl = false;
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "无法连接到服务器", "错误", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        // 发送按钮点击事件处理
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String text = inputField.getText();
                if (!text.isEmpty()) {
                    try {
                        outputStream.write(text.getBytes());
                        inputField.setText("");
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        // 离线按钮点击事件处理
        offlineButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    // 向服务器发送离线标识消息，这里假设为"OFFLINE"
                    outputStream.write("已离线".getBytes());
                    // 关闭与服务器的连接
                    socket.close();
                    // 设置停止线程的标志位为false，使接收消息线程停止
                    clientThreadControl = false;
                    // 设置发送按钮和离线按钮不可用，避免误操作
                    sendButton.setEnabled(false);
                    offlineButton.setEnabled(false);

                    JOptionPane.showMessageDialog(TCPClient1.this, "已离线", "提示", JOptionPane.INFORMATION_MESSAGE);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    private void appendMessage(String message) {
        SwingUtilities.invokeLater(() -> {
            chatArea.append(message + "\n");
        });
    }

    public static void start() {
        // 创建一个面板用于放置输入框
        JPanel panel = new JPanel(new GridLayout(3, 2));

        // 创建用于输入客户端名称的文本框
        JTextField clientNameField = new JTextField();
        // 创建用于输入服务器IP地址的文本框
        JTextField serverIpField = new JTextField("leafdomain.cn");
        // 创建用于输入服务器端口号的文本框
        JTextField serverPortField = new JTextField("8089");

        // 将标签和文本框添加到面板中
        panel.add(new JLabel("客户端名称："));
        panel.add(clientNameField);
        panel.add(new JLabel("服务器IP地址："));
        panel.add(serverIpField);
        panel.add(new JLabel("服务器端口号："));
        panel.add(serverPortField);

        while (true) {
            // 弹出对话框并获取用户输入
            int option = JOptionPane.showConfirmDialog(null, panel, "请输入客户端信息", JOptionPane.OK_CANCEL_OPTION);
            if (option == JOptionPane.OK_OPTION) {
                String clientName = clientNameField.getText();
                String serverIp = serverIpField.getText();
                String serverPortStr = serverPortField.getText();
                if (clientName == null || clientName.trim().isEmpty()) {
                    JOptionPane.showMessageDialog(null, "客户端名称不能为空，请重新输入！", "错误", JOptionPane.ERROR_MESSAGE);
                    continue;
                }

                if (serverIp == null || serverIp.trim().isEmpty()) {
                    JOptionPane.showMessageDialog(null, "服务器IP地址不能为空，请重新输入！", "错误", JOptionPane.ERROR_MESSAGE);
                    continue;
                }

                if (serverPortStr == null || serverPortStr.trim().isEmpty()) {
                    JOptionPane.showMessageDialog(null, "服务器端口号不能为空，请重新输入！", "错误", JOptionPane.ERROR_MESSAGE);
                    continue;
                }
                int serverPort;
                try {
                    serverPort = Integer.parseInt(serverPortStr);
                } catch (NumberFormatException e) {
                    JOptionPane.showMessageDialog(null, "服务器端口号必须是数字，请重新输入！", "错误", JOptionPane.ERROR_MESSAGE);
                    continue;
                }
                SwingUtilities.invokeLater(() -> {
                    TCPClient1 clientGUI = new TCPClient1(clientName, serverIp, serverPort);
                    clientGUI.setVisible(true);
                });
                break;
            } else {
                // 如果用户点击了取消按钮, 则退出
                System.exit(0);
            }
        }
    }
    public static void main(String[] args) {
        start();
    }
}